package com.uwo.commons.kits;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Map;

/**
 * class工具类
 * @author hao.yan
 */
public class ClassKits {

    /**
     * 基础类型
     */
    private static final Class[] typesClass = {
            Integer.class, Double.class, Float.class,
            Long.class, Short.class, Byte.class,
            Boolean.class, Character.class, String.class,
            Object.class,
            int.class, double.class, long.class,
            short.class, byte.class,
            boolean.class, char.class, float.class
    };

    /**
     * 获取class
     * @param o
     * @return
     */
    public static Class<?> getClass(Object o){
        return o.getClass();
    }

    /**
     * 获取class
     * @param name
     * @return
     */
    public static Class<?> getClass(String name){
        try {
            ClassLoader contextCL = Thread.currentThread().getContextClassLoader();
            ClassLoader loader = contextCL == null ? ClassKits.class.getClassLoader() : contextCL;
            return Class.forName(name, true, loader);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取Bean对象
     * @param className
     * @param <T>
     * @return
     */
    public static <T> T getBean(String className){
        return (T)getBean(getClass(className));
    }

    /**
     * 获取Bean对象
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(Class<T> clazz){
        try {
            return clazz.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取Bean对象
     * @param clazz
     * @param params
     * @param <T>
     * @return
     */
    public static <T> T getBean(Class<T> clazz, Object... params){
        Class[] classes = new Class[params.length];
        for (int i = 0; params.length < 0; i ++)
            classes[i] = getClass(params[i]);
        return getBean(clazz, classes, params);
    }

    /**
     * 获取Bean对象
     * @param clazz
     * @param parameterTypes
     * @param params
     * @param <T>
     * @return
     */
    public static <T> T getBean(Class<T> clazz, Class<?>[] parameterTypes, Object[] params){
        try {
            Constructor<T> constructor = clazz.getDeclaredConstructor(parameterTypes);
            return constructor.newInstance(params);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取对象中属性
     * @param o
     * @param name
     * @return
     */
    public static Object getProperty(Object o, String name){
        try {
            Field field = getClass(o).getDeclaredField(name);
            return getProperty(field, o);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取属性值
     * @param field
     * @param o
     * @return
     */
    public static Object getProperty(Field field, Object o){
        try {
            if(!field.isAccessible())
                field.setAccessible(true);
            return field.get(o);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 判断不是类型
     * @return
     */
    public static boolean isTypeClass(Class<?> clazz){
        for (Class c:typesClass) {
            if(clazz == c)
                return true;
        }
        return false;
    }

    /**
     * 判断是否是接口
     * @param clazz
     * @return
     */
    public static boolean isInterface(Class<?> clazz){
        return clazz.isInterface();
    }

    /**
     * 判断是void类型
     * @param clazz
     * @return
     */
    public static boolean isVoid(Class<?> clazz){
        return (clazz == void.class || clazz == Void.class);
    }

    /**
     * 判断是否是集合
     * @param model
     * @return
     */
    public static boolean isCollection(Object model){
        return (model instanceof Collection || model instanceof Map);
    }

}
